home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume25 / sockdemo < prev    next >
Encoding:
Internet Message Format  |  1991-12-13  |  28.6 KB

  1. Subject: v25i034: sockdemo - demo for berkeley socket interface
  2. Newsgroups: comp.sources.unix
  3. Approved: vixie@pa.dec.com
  4.  
  5. Submitted-By: Blair P Houghton <bhoughto@pima.intel.com>
  6. Posting-Number: Volume 25, Issue 34
  7. Archive-Name: sockdemo
  8.  
  9. This package is intended for demonstration and education.
  10. I've tried to keep the demos as simple as possible while
  11. implementing the basic functioning of Unix and Internet
  12. sockets.
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 1 (of 1)."
  21. # Contents:  MANIFEST Makefile README disockl.c disockt.c isockl.c
  22. #   isockt.c sockl.c sockl.h sockl.nroff-man sockt.c
  23. # Wrapped by vixie@cognition.pa.dec.com on Fri Dec 13 14:15:36 1991
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  27. else
  28. echo shar: Extracting \"'MANIFEST'\" \(455 characters\)
  29. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  30. X   File Name        Archive #    Description
  31. X-----------------------------------------------------------
  32. X MANIFEST                   1    This shipping list
  33. X Makefile                   1    
  34. X README                     1    
  35. X disockl.c                  1    
  36. X disockt.c                  1    
  37. X isockl.c                   1    
  38. X isockt.c                   1    
  39. X sockl.c                    1    
  40. X sockl.h                    1    
  41. X sockl.nroff-man            1    
  42. X sockt.c                    1    
  43. END_OF_FILE
  44. if test 455 -ne `wc -c <'MANIFEST'`; then
  45.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  46. fi
  47. # end of 'MANIFEST'
  48. fi
  49. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  50.   echo shar: Will not clobber existing file \"'Makefile'\"
  51. else
  52. echo shar: Extracting \"'Makefile'\" \(1275 characters\)
  53. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  54. X# Makefile for socket demo collection
  55. X#(C) 1991 Blair P. Houghton, All Rights Reserved, copying and
  56. X#distribution permitted with copyright intact.
  57. X
  58. X# gcc screws up gethostbyname() with my library; try it on yours
  59. X#CC = gcc -ansi -pedantic -Wall
  60. X
  61. X# debugging is more fun if the symbols and trace-hooks are intact...
  62. CFLAGS = -g
  63. X
  64. X# shar'ring is rather specific to the sort of shar(1local) one possesses...
  65. SHAR = /usr/local/bin/xshar -vsMDc
  66. X#SHAR = shar
  67. X
  68. all: disock isock sock
  69. X
  70. X
  71. X# unix-local-connection example
  72. sock: sockl sockt
  73. X
  74. sockl: sockl.c sockl.h
  75. X    $(CC) $(CFLAGS) -o sockl sockl.c
  76. X
  77. sockt: sockt.c sockl.h
  78. X    $(CC) $(CFLAGS) -o sockt sockt.c
  79. X
  80. sockl.h:
  81. X
  82. X
  83. X# internet-connection example
  84. isock: isockl isockt
  85. X
  86. isockl: isockl.c
  87. X    $(CC) $(CFLAGS) -o isockl isockl.c
  88. X
  89. isockt: isockt.c
  90. X    $(CC) $(CFLAGS) -o isockt isockt.c
  91. X
  92. X
  93. X# internet-connection example using disconnected transmittal
  94. disock: disockl disockt
  95. X
  96. disockl: disockl.c
  97. X    $(CC) $(CFLAGS) -o disockl disockl.c
  98. X
  99. disockt: disockt.c
  100. X    $(CC) $(CFLAGS) -o disockt disockt.c
  101. X
  102. X
  103. man: sockl.1
  104. X    nroff -man sockl.nroff-man > sockl.1
  105. sockl.1:
  106. X
  107. X
  108. shar:
  109. X    $(SHAR) README sockl.nroff-man Makefile        \
  110. sockl.c sockt.c isockl.c isockt.c disockl.c disockt.c    \
  111. sockl.h > sockl.shar
  112. X
  113. X
  114. clean:
  115. X    rm -f sockl sockt isockl isockt disockl disockt sockl.1
  116. END_OF_FILE
  117. if test 1275 -ne `wc -c <'Makefile'`; then
  118.     echo shar: \"'Makefile'\" unpacked with wrong size!
  119. fi
  120. # end of 'Makefile'
  121. fi
  122. if test -f 'README' -a "${1}" != "-c" ; then 
  123.   echo shar: Will not clobber existing file \"'README'\"
  124. else
  125. echo shar: Extracting \"'README'\" \(2533 characters\)
  126. sed "s/^X//" >'README' <<'END_OF_FILE'
  127. X/* (C) 1991 Blair P. Houghton, All Rights Reserved, copying and */
  128. X/* distribution permitted with copyright intact.        */
  129. X
  130. This package is intended for demonstration and education.
  131. I've tried to keep the demos as simple as possible while
  132. implementing the basic functioning of Unix and Internet
  133. sockets.
  134. X
  135. Socket demo programs:
  136. X
  137. X    sockl:    Socket Listener.  Creates an AF_UNIX socket (one handled
  138. X        only by the local kernel), listens for and accepts a
  139. X        SOCK_STREAM (reliable, file-i/o-like) connection, and
  140. X        prints the sent data to stdout.  No arguments.  Initially
  141. X        prints data including the port number to be given on the
  142. X        command line when starting sockt.
  143. X    sockt:      Socket Talker.  Connects to an AF_UNIX port given as
  144. X        argument and sends a few lines of text.  The connection
  145. X        is of SOCK_STREAM type.  (This program is impressively
  146. X        simple).
  147. X
  148. X    isockl:     Internet Socket Listener.  Like sockl.c, but opens an
  149. X        AF_INET socket (an Internet communications channel,
  150. X        handled by the ethernet driver).
  151. X    isockt:     Internet Socket Talker.  Like sockt, but takes a machine
  152. X        name as first argument and port number as second argument.
  153. X
  154. X    disockl:    Datagram Internet Socket Listener.  Like isockl, but the
  155. X        communications style is SOCK_DGRAM.
  156. X    disockt:    Datagram Internet Socket Talker.  Like isockt, but the
  157. X        communications style is SOCK_DGRAM.
  158. X
  159. Make targets include the names of the programs, plus "all",
  160. X"man", "shar", and "clean."  The sources are compiled by
  161. default with your make(1)'s default cc(1), but can be
  162. compiled with GNU's gcc in pedantic ANSI mode; however, gcc
  163. will use whatever (possibly flakey) library it's been
  164. installed with, so check the results carefully if you do
  165. use gcc.  It's also compiled cleanly under some real ANSI
  166. compilers.
  167. X
  168. Sockets aren't the most portable of code (in fact, ANSI C
  169. makes no provision for them).  These demos were developed
  170. under Ultrix and tested on HP/Apollo BSD.  I fixed some
  171. X#include's so it would compile on both systems.
  172. X
  173. The results when the programs are run are okay on Ultrix
  174. but disockl bombs immediately on the Apollo; and, strings
  175. sent over the sockets on the Apollo have grot on the end.
  176. This was the expected result of the experiment; it has to
  177. do with the fact that Ultrix and Apollo use different
  178. structures and semantics for socket data.  If you're using
  179. Apollos or some other system and these programs don't work
  180. out of the box, try hacking them to use the TCP/IP structs
  181. implemented for your machine.
  182. X
  183. X                --Blair
  184. X                  "Class dismissed."
  185. END_OF_FILE
  186. if test 2533 -ne `wc -c <'README'`; then
  187.     echo shar: \"'README'\" unpacked with wrong size!
  188. fi
  189. # end of 'README'
  190. fi
  191. if test -f 'disockl.c' -a "${1}" != "-c" ; then 
  192.   echo shar: Will not clobber existing file \"'disockl.c'\"
  193. else
  194. echo shar: Extracting \"'disockl.c'\" \(3204 characters\)
  195. sed "s/^X//" >'disockl.c' <<'END_OF_FILE'
  196. X/* sockl.c -- set up an INTERNET DGRAM socket and listen on it */
  197. X/* (C) 1991 Blair P. Houghton, All Rights Reserved, copying and */
  198. X/* distribution permitted with copyright intact.        */
  199. X
  200. X/* a DGRAM receiver is thoroughly independent of the sender */
  201. X
  202. X#include <stdio.h>
  203. X#include <sys/types.h>
  204. X#include <sys/socket.h>
  205. X#include <netinet/in.h>
  206. X#include <fcntl.h>
  207. X
  208. X#ifdef __STDC__
  209. extern void    exit( int );
  210. extern void    perror( char * );
  211. extern int    printf( char *, ... );
  212. extern int    bind( int, struct sockaddr *, int );
  213. extern int    socket( int, int, int );
  214. extern int    read( int, char *, unsigned );
  215. extern char *    strcpy( char *, char *b );
  216. extern int    fcntl( int, int, int );
  217. extern int    accept( int, struct sockaddr *, int * );
  218. extern int    listen( int, int );
  219. extern int    unlink( char * );
  220. extern int    getsockname( int, struct sockaddr *, int * );
  221. extern int    recvfrom( int, char *, int, int, struct sockaddr *, int );
  222. X
  223. void main( int argc, char *argv[] )
  224. X#else
  225. main( argc, argv )
  226. int argc; char *argv[];
  227. X#endif
  228. X{
  229. X    int sock;                /* fd for the socket */
  230. X    struct sockaddr_in sockaddr;    /* sytem's location of the socket */
  231. X    struct sockaddr_in caller;        /* id of foreign calling process */
  232. X    int sockaddr_in_length = sizeof(struct sockaddr_in);
  233. X    char buf[BUFSIZ];
  234. X    int read_ret;
  235. X    int fromlen = sizeof(struct sockaddr_in);
  236. X    char acknowledgement[BUFSIZ];
  237. X
  238. X    /*
  239. X     *  open a net socket, using dgram (packetized, nonconnected)
  240. X     *  mode, with protocol irrelevant ( == 0 )
  241. X     */
  242. X    if ( (sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
  243. X    char s[BUFSIZ];
  244. X    sprintf( s, "%s: can't assign fd for socket", argv[0] );
  245. X    perror(s);
  246. X    exit(__LINE__);
  247. X    }
  248. X
  249. X   /*
  250. X    *  register the socket
  251. X    */
  252. X    sockaddr.sin_family = AF_INET;
  253. X    sockaddr.sin_addr.s_addr = INADDR_ANY;    /* not choosy about who calls */
  254. X    sockaddr.sin_port = 0;            /* ??? why 0? */
  255. X
  256. X    if ( bind( sock, (struct sockaddr *) &sockaddr, sizeof sockaddr ) < 0 ) {
  257. X    char s[BUFSIZ];
  258. X    sprintf( s, "%s: can't bind socket (%d)", argv[0], sock );
  259. X    perror(s);
  260. X    exit(__LINE__);
  261. X    }
  262. X
  263. X   /*
  264. X    *  get port number
  265. X    */
  266. X    if ( getsockname(sock, (struct sockaddr *) &sockaddr, (int *)&sockaddr_in_length)
  267. X     < 0 ) {
  268. X    char s[BUFSIZ];
  269. X    sprintf( s, "%s: can't get port number of socket (%d)",
  270. X        argv[0], sock );
  271. X    perror(s);
  272. X    exit(__LINE__);
  273. X    }
  274. X
  275. X    printf("opened socket as fd (%d) on port (%d) for dgram i/o\n",
  276. X        sock, ntohs(sockaddr.sin_port) );
  277. X
  278. X    printf(
  279. X"struct sockaddr_in {\n\
  280. X    sin_family        = %d\n\
  281. X    sin_addr.s_addr    = %d\n\
  282. X    sin_port        = %d\n\
  283. X} sockaddr;\n"
  284. X, sockaddr.sin_family
  285. X, sockaddr.sin_addr.s_addr
  286. X, ntohs(sockaddr.sin_port)
  287. X    );
  288. X    fflush(stdout);
  289. X
  290. X    /* read and print lines until the cows come home */
  291. X    while ( (read_ret = recvfrom( sock, buf, sizeof buf,
  292. X                  0, (struct sockaddr *) &caller,
  293. X                  sizeof caller)
  294. X        ) > 0 ) {
  295. X    printf( "%s: read (from caller (%s, %d)) socket as follows:\n(%s)\n",
  296. X        argv[0],
  297. X        inet_ntoa(caller.sin_addr),
  298. X        ntohs(caller.sin_port),
  299. X        buf ); 
  300. X    fflush(stdout);
  301. X    }
  302. X
  303. X    if ( read_ret < 0 ) {
  304. X    char s[BUFSIZ];
  305. X    sprintf( s, "%s: error reading socket", argv[0] );
  306. X    perror(s);
  307. X    exit(__LINE__);
  308. X    }
  309. X
  310. X    /* loop ended normally:  read() returned NULL */
  311. X    exit(0);
  312. X}
  313. END_OF_FILE
  314. if test 3204 -ne `wc -c <'disockl.c'`; then
  315.     echo shar: \"'disockl.c'\" unpacked with wrong size!
  316. fi
  317. # end of 'disockl.c'
  318. fi
  319. if test -f 'disockt.c' -a "${1}" != "-c" ; then 
  320.   echo shar: Will not clobber existing file \"'disockt.c'\"
  321. else
  322. echo shar: Extracting \"'disockt.c'\" \(2867 characters\)
  323. sed "s/^X//" >'disockt.c' <<'END_OF_FILE'
  324. X/* disockt.c -- open an internet socket and talk dgrams into it */
  325. X/* (C) 1991 Blair P. Houghton, All Rights Reserved, copying and */
  326. X/* distribution permitted with copyright intact.        */
  327. X
  328. X#include <stdio.h>
  329. X#include <sys/types.h>
  330. X#include <sys/socket.h>
  331. X#include <netinet/in.h>
  332. X#include <netdb.h>
  333. X#include <math.h>
  334. X
  335. X#ifdef __STDC__
  336. extern void    perror( char * );
  337. extern int    bind( int, struct sockaddr *, int );
  338. extern int    socket( int, int, int );
  339. extern int    write( int, char *, unsigned );
  340. extern char *    strcpy( char *, char *b );
  341. extern int    strlen( char * );
  342. extern void    exit( int );
  343. extern int    connect( int, struct sockaddr *, int );
  344. extern struct hostent *    gethostbyname( char * );
  345. extern int    fprintf( FILE *, char *, ... );
  346. extern int    atoi( char * );
  347. extern void    bcopy( char *, char *b, int );
  348. X#endif
  349. X
  350. char *line[] = {
  351. X    "Mary had a little lamb;\n",
  352. X    "Its fleece was white as snow;\n",
  353. X    "And everywhere that Mary went,\n",
  354. X    "She told everyone that Edison invented\nthe telephone before Bell did.\n"
  355. X};
  356. int n_line = 4;
  357. X
  358. X/*
  359. X *  argv 0 is program name; argv 1 is remote host; argv 2 is
  360. X *  port number of listener on remote host
  361. X */
  362. X#ifdef __STDC__
  363. void main( int argc, char *argv[] )
  364. X#else
  365. main(argc,argv)
  366. int argc; char *argv[];
  367. X#endif
  368. X{
  369. X
  370. X    int plug;                /* socket to "plug" into the socket */
  371. X    struct sockaddr_in socketname;    /* mode, addr, and port    */
  372. X                    /* data for the socket    */
  373. X    struct hostent *remote_host;    /* internet numbers, names */
  374. X    extern int n_line;
  375. X    extern char *line[];
  376. X    char buf[BUFSIZ];
  377. X    int i, sendflags;
  378. X
  379. X    /* make an internet-transmitted, dgram-i/o-style, protocol-whatever plug */
  380. X    if ( (plug = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 )
  381. X    perror(argv[0]);
  382. X
  383. X    /* plug it into the listening socket */
  384. X    socketname.sin_family = AF_INET;
  385. X    if ( (remote_host = gethostbyname( argv[1] )) == (struct hostent *)NULL ) {
  386. X    fprintf( stderr, "%s: unknown host: %s\n",
  387. X         argv[0], argv[1] );
  388. X    exit(__LINE__);
  389. X    }
  390. X    (void) bcopy( (char *)remote_host->h_addr, (char *) &socketname.sin_addr,
  391. X          remote_host->h_length );
  392. X    socketname.sin_port = htons(atoi(argv[2]));
  393. X
  394. X    printf("sending %d dgrams to:\n", n_line);
  395. X    printf(
  396. X"struct sockaddr_in {\n\
  397. X    sin_family        = %d\n\
  398. X    sin_addr.s_addr    = %s\n\
  399. X    sin_port         = %d\n\
  400. X} socketname;\n"
  401. X, socketname.sin_family
  402. X, inet_ntoa(socketname.sin_addr)
  403. X/* , socketname.sin_addr.s_addr -- gives unsigned long, not struct in_addr */
  404. X, ntohs(socketname.sin_port)
  405. X    );
  406. X
  407. X    /* say something into it; something historic */
  408. X    sendflags = 0;
  409. X    for ( i = 0; i < n_line; i++ ) {
  410. X    sleep(1);
  411. X    if ( sendto( plug,
  412. X             line[i], 1+strlen(line[i]),
  413. X             sendflags,
  414. X             (struct sockaddr *)&socketname, sizeof socketname )
  415. X         < 0 ) {
  416. X        perror(argv[0]);
  417. X        exit(__LINE__);
  418. X    }
  419. X    }
  420. X    
  421. X    /* all the socket connections are closed automatically */
  422. X    exit(0);
  423. X}
  424. END_OF_FILE
  425. if test 2867 -ne `wc -c <'disockt.c'`; then
  426.     echo shar: \"'disockt.c'\" unpacked with wrong size!
  427. fi
  428. # end of 'disockt.c'
  429. fi
  430. if test -f 'isockl.c' -a "${1}" != "-c" ; then 
  431.   echo shar: Will not clobber existing file \"'isockl.c'\"
  432. else
  433. echo shar: Extracting \"'isockl.c'\" \(4065 characters\)
  434. sed "s/^X//" >'isockl.c' <<'END_OF_FILE'
  435. X/* isockl.c -- set up an INTERNET STREAM socket and listen on it */
  436. X/* (C) 1991 Blair P. Houghton, All Rights Reserved, copying and */
  437. X/* distribution permitted with copyright intact.        */
  438. X
  439. X/* a stream (a socket opened using SOCK_STREAM) requires the use of
  440. listen() and accept() in a receiver, and connect() in a sender */
  441. X
  442. X#include <stdio.h>
  443. X#include <sys/types.h>
  444. X#include <sys/socket.h>
  445. X#include <netinet/in.h>
  446. X#include <fcntl.h>
  447. X
  448. X#ifdef __STDC__
  449. extern void    exit( int );
  450. extern void    perror( char * );
  451. extern int    printf( char *, ... );
  452. extern int    bind( int, struct sockaddr *, int );
  453. extern int    socket( int, int, int );
  454. extern int    read( int, char *, unsigned );
  455. extern char *    strcpy( char *, char *b );
  456. extern int    fcntl( int, int, int );
  457. extern int    accept( int, struct sockaddr *, int * );
  458. extern int    listen( int, int );
  459. extern int    unlink( char * );
  460. extern int    getsockname( int, struct sockaddr *, int * );
  461. X
  462. void main( int argc, char *argv[] )
  463. X#else
  464. main( argc, argv )
  465. int argc; char *argv[];
  466. X#endif
  467. X{
  468. X    int sock;                /* fd for the listening socket */
  469. X    int ear;                /* fd for the working socket */
  470. X    struct sockaddr_in sockaddr;    /* sytem's location of the socket */
  471. X    struct sockaddr_in caller;        /* id of foreign calling process */
  472. X    int sockaddr_in_length = sizeof(struct sockaddr_in);
  473. X    char buf[BUFSIZ];
  474. X    int read_ret;
  475. X    int fromlen = sizeof(struct sockaddr_in);
  476. X    char acknowledgement[BUFSIZ];
  477. X
  478. X    /*
  479. X     *  open a net socket, using stream (file-style i/o)
  480. X     *  mode, with protocol irrelevant ( == 0 )
  481. X     */
  482. X    if ( (sock = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
  483. X    char s[BUFSIZ];
  484. X    sprintf( s, "%s: can't assign fd for socket", argv[0] );
  485. X    perror(s);
  486. X    exit(__LINE__);
  487. X    }
  488. X
  489. X   /*
  490. X    *  register the socket
  491. X    */
  492. X    sockaddr.sin_family = AF_INET;
  493. X    sockaddr.sin_addr.s_addr = INADDR_ANY;    /* not choosy about who calls */
  494. X    sockaddr.sin_port = 0;
  495. X
  496. X    if ( bind( sock, (struct sockaddr *) &sockaddr, sizeof sockaddr ) < 0 ) {
  497. X    char s[BUFSIZ];
  498. X    sprintf( s, "%s: can't bind socket (%d)", argv[0], sock );
  499. X    perror(s);
  500. X    exit(__LINE__);
  501. X    }
  502. X
  503. X   /*
  504. X    *  get port number
  505. X    */
  506. X    if ( getsockname( sock, (struct sockaddr *) &sockaddr,
  507. X              (int *)&sockaddr_in_length )
  508. X     < 0 ) {
  509. X    char s[BUFSIZ];
  510. X    sprintf( s, "%s: can't get port number of socket (%d)",
  511. X        argv[0], sock );
  512. X    perror(s);
  513. X    exit(__LINE__);
  514. X    }
  515. X
  516. X    printf("opened socket as fd (%d) on port (%d) for stream i/o\n",
  517. X        sock, ntohs(sockaddr.sin_port) );
  518. X
  519. X    printf(
  520. X"struct sockaddr_in {\n\
  521. X    sin_family        = %d\n\
  522. X    sin_addr.s_addr    = %d\n\
  523. X    sin_port        = %d\n\
  524. X} sockaddr;\n"
  525. X, sockaddr.sin_family
  526. X, sockaddr.sin_addr.s_addr
  527. X, ntohs(sockaddr.sin_port)
  528. X    );
  529. X
  530. X
  531. X    /* put an ear to the socket, listening for a knock-knock-knocking */
  532. X    listen( sock, 1 );                /* 1: only one queue slot */
  533. X    /* ear will be a temporary (non-reusable) socket different from sock */
  534. X    if ( (ear = accept( sock, (struct sockaddr *)&caller, &fromlen )) < 0 ) {
  535. X    perror(argv[0]);
  536. X    exit(__LINE__);
  537. X    }
  538. X
  539. X    /* print calling process' identification */
  540. X    printf(
  541. X"struct sockaddr_in {\n\
  542. X    sin_family        = %d\n\
  543. X    sin_addr.s_addr    = %s\n\
  544. X    sin_port (!!!)    = %d\n\
  545. X} caller;\n"
  546. X, caller.sin_family
  547. X, inet_ntoa(caller.sin_addr)
  548. X/* , caller.sin_addr.s_addr -- gives an unsigned long, not a struct in_addr */
  549. X, ntohs(caller.sin_port)
  550. X    );
  551. X
  552. X    /* optional ack; demonstrates bidirectionality */
  553. X    gethostname(buf, sizeof buf);
  554. X    sprintf( acknowledgement, "Welcome, from sunny %s (%s.%d)\n",
  555. X        buf,
  556. X        buf,
  557. X        ntohs(sockaddr.sin_port)
  558. X        );
  559. X    /* write into the ear; the sock is _only_for_rendezvous_ */
  560. X    if ( write ( ear, acknowledgement, sizeof acknowledgement ) < 1 )
  561. X    perror(argv[0]);
  562. X
  563. X    /* read lines until the stream closes */
  564. X    while ( (read_ret = read( ear, buf, sizeof buf )) > 0 )
  565. X    printf( "%s: read from socket as follows:\n(%s)\n", argv[0], buf ); 
  566. X
  567. X    if ( read_ret < 0 ) {
  568. X    char s[BUFSIZ];
  569. X    sprintf( s, "%s: error reading socket", argv[0] );
  570. X    perror(s);
  571. X    exit(__LINE__);
  572. X    }
  573. X
  574. X    /* loop ended normally:  read() returned NULL */
  575. X    exit(0);
  576. X}
  577. END_OF_FILE
  578. if test 4065 -ne `wc -c <'isockl.c'`; then
  579.     echo shar: \"'isockl.c'\" unpacked with wrong size!
  580. fi
  581. # end of 'isockl.c'
  582. fi
  583. if test -f 'isockt.c' -a "${1}" != "-c" ; then 
  584.   echo shar: Will not clobber existing file \"'isockt.c'\"
  585. else
  586. echo shar: Extracting \"'isockt.c'\" \(2589 characters\)
  587. sed "s/^X//" >'isockt.c' <<'END_OF_FILE'
  588. X/* isockt.c -- open an internet socket and talk into it */
  589. X/* (C) 1991 Blair P. Houghton, All Rights Reserved, copying and */
  590. X/* distribution permitted with copyright intact.        */
  591. X
  592. X#include <stdio.h>
  593. X#include <sys/types.h>
  594. X#include <sys/socket.h>
  595. X#include <netinet/in.h>
  596. X#include <netdb.h>
  597. X#include <math.h>
  598. X
  599. X#ifdef __STDC__
  600. extern void    perror( char * );
  601. extern int    bind( int, struct sockaddr *, int );
  602. extern int    socket( int, int, int );
  603. extern int    write( int, char *, unsigned );
  604. extern char *    strcpy( char *, char *b );
  605. extern int    strlen( char * );
  606. extern void    exit( int );
  607. extern int    connect( int, struct sockaddr *, int );
  608. extern struct hostent *    gethostbyname( char * );
  609. extern int    fprintf( FILE *, char *, ... );
  610. extern int    atoi( char * );
  611. extern void    bcopy( char *, char *b, int );
  612. X#endif
  613. X
  614. char *line[] = {
  615. X    "Mary had a little lamb;\n",
  616. X    "Its fleece was white as snow;\n",
  617. X    "And everywhere that Mary went,\n",
  618. X    "She told everyone that Edison invented\nthe telephone before Bell did.\n"
  619. X};
  620. int n_line = 4;
  621. X
  622. X/*
  623. X *  arg 0 is program name; arg 1 is remote host; arg 2 is
  624. X *  port number of listener on remote host
  625. X */
  626. X#ifdef __STDC__
  627. void main( int argc, char *argv[] )
  628. X#else
  629. main(argc,argv)
  630. int argc; char *argv[];
  631. X#endif
  632. X{
  633. X
  634. X    int plug;                /* socket to "plug" into the socket */
  635. X    struct sockaddr_in socketname;    /* mode, addr, and port data for the socket */
  636. X    struct hostent *remote_host;    /* internet numbers, names */
  637. X    extern int n_line;
  638. X    extern char *line[];
  639. X    char buf[BUFSIZ];
  640. X    int i;
  641. X
  642. X    /* make an internet-transmitted, file-i/o-style, protocol-whatever plug */
  643. X    if ( (plug = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
  644. X    perror(argv[0]);
  645. X
  646. X    /* plug it into the listening socket */
  647. X    socketname.sin_family = AF_INET;
  648. X    if ( (remote_host = gethostbyname( argv[1] )) == (struct hostent *)NULL ) {
  649. X    fprintf( stderr, "%s: unknown host: %s\n",
  650. X         argv[0], argv[1] );
  651. X    exit(__LINE__);
  652. X    }
  653. X    (void) bcopy( (char *)remote_host->h_addr, (char *) &socketname.sin_addr,
  654. X          remote_host->h_length );
  655. X    socketname.sin_port = htons(atoi(argv[2]));
  656. X
  657. X    if ( connect( plug, (struct sockaddr *) &socketname,
  658. X          sizeof socketname ) < 0 ) {
  659. X    perror(argv[0]);
  660. X    exit(__LINE__);
  661. X    }
  662. X
  663. X    /* wait for ack */
  664. X    if ( read( plug, buf, sizeof buf ) > 0 )
  665. X    printf(buf);
  666. X
  667. X    /* say something into it; something historic */
  668. X    for ( i = 0; i < n_line; i++ ) {
  669. X    sleep(1);
  670. X    if ( write( plug, line[i], strlen(line[i]) ) < 0 ) {
  671. X        perror(argv[0]);
  672. X        exit(__LINE__);
  673. X    }
  674. X    }
  675. X    
  676. X    /* all the socket connections are closed automatically */
  677. X    exit(0);
  678. X}
  679. END_OF_FILE
  680. if test 2589 -ne `wc -c <'isockt.c'`; then
  681.     echo shar: \"'isockt.c'\" unpacked with wrong size!
  682. fi
  683. # end of 'isockt.c'
  684. fi
  685. if test -f 'sockl.c' -a "${1}" != "-c" ; then 
  686.   echo shar: Will not clobber existing file \"'sockl.c'\"
  687. else
  688. echo shar: Extracting \"'sockl.c'\" \(3092 characters\)
  689. sed "s/^X//" >'sockl.c' <<'END_OF_FILE'
  690. X/* sockl.c -- set up a UNIX STREAM socket and listen on it */
  691. X/* (C) 1991 Blair P. Houghton, All Rights Reserved, copying and */
  692. X/* distribution permitted with copyright intact.        */
  693. X
  694. X/* a stream (a socket opened using SOCK_STREAM) requires the use of
  695. listen() and accept() in a receiver, and connect() in a sender */
  696. X
  697. X#include <stdio.h>
  698. X#include <sys/types.h>
  699. X#include <sys/socket.h>
  700. X#include <sys/un.h>
  701. X#include <fcntl.h>
  702. X/* include sockl.h only after <sys/socket.h> */
  703. X#include "sockl.h" 
  704. X
  705. X#ifdef __STDC__
  706. extern void    exit( int );
  707. extern void    perror( char * );
  708. extern int    printf( char *, ... );
  709. extern int    bind( int, struct sockaddr *, int );
  710. extern int    socket( int, int, int );
  711. extern int    read( int, char *, unsigned );
  712. extern char *    strcpy( char *, char *b );
  713. extern int    fcntl( int, int, int );
  714. extern int    accept( int, struct sockaddr *, int * );
  715. extern int    listen( int, int );
  716. extern int    unlink( char * );
  717. X
  718. void main( int argc, char *argv[] )
  719. X#else
  720. main(argc,argv)
  721. int argc; char *argv[];
  722. X#endif
  723. X{
  724. X    int sock;                /* fd for the actual socket */
  725. X    int ear;                /* fd for the working socket */
  726. X    struct sockaddr_un sockaddr;    /* sytem's location of the socket */
  727. X    char buf[BUFSIZ];
  728. X    int read_ret;
  729. X    int f_ret;
  730. X
  731. X    /*
  732. X     *  open a unix (local) socket, using stream (file-style i/o)
  733. X     *  mode, with protocol irrelevant ( == 0 ) (the protocol is
  734. X     *  generally determined by the connection style: tcp for stream,
  735. X     *  udp for datagrams, but this is not immutable nor all the
  736. X     *  protocols for these styles).
  737. X     */
  738. X    if ( (sock = socket( AF_UNIX, SOCK_STREAM, 0 )) < 0 ) {
  739. X    char s[BUFSIZ];
  740. X    sprintf( s, "%s: can't assign fd for socket", argv[0] );
  741. X    perror(s);
  742. X    exit(__LINE__);
  743. X    }
  744. X
  745. X    /* place a filename in the filesystem for other processes to find */
  746. X    sockaddr.sun_family = AF_UNIX;
  747. X    (void) strcpy( sockaddr.sun_path, SOCKET_PATH_NAME );
  748. X
  749. X    if ( bind( sock, (struct sockaddr *) &sockaddr, sizeof sockaddr ) < 0 ) {
  750. X    char s[BUFSIZ];
  751. X    sprintf( s, "%s: can't bind socket (%d) to pathname (%s)",
  752. X        argv[0], sock, sockaddr.sun_path );
  753. X    perror(s);
  754. X    exit(__LINE__);
  755. X    }
  756. X
  757. X    printf("opened socket as fd (%d) at path (%s) for stream i/o\n",
  758. X        sock, sockaddr.sun_path);
  759. X
  760. X    /* put an ear to the socket, listening for a knock-knock-knocking */
  761. X    listen( sock, 1 );                /* 1: only one queue slot */
  762. X    /* ear will be a temporary (non-reusable) socket different from sock */
  763. X    if ( (ear = accept( sock, (struct sockaddr *)NULL, (int *)NULL )) < 0 ) {
  764. X    perror(argv[0]);
  765. X    exit(__LINE__);
  766. X    }
  767. X
  768. X    /* read lines and print until the stream closes */
  769. X    while ( (read_ret = read( ear, buf, sizeof buf )) > 0 )
  770. X    printf( "\n%s: read from socket as follows:\n(%s)", argv[0], buf ); 
  771. X
  772. X    if ( read_ret < 0 ) {
  773. X    char s[BUFSIZ];
  774. X    sprintf( s, "%s: error reading socket", argv[0] );
  775. X    perror(s);
  776. X    exit(__LINE__);
  777. X    }
  778. X
  779. X   /*
  780. X    *  lots of things will close automatically: sock, ear;
  781. X    *  but, this one must be done cleanly:
  782. X    */
  783. X
  784. X    /* rm filename */
  785. X    unlink( SOCKET_PATH_NAME );
  786. X
  787. X    /* loop ended normally:  read() returned NULL */
  788. X    exit(0);
  789. X}
  790. X
  791. END_OF_FILE
  792. if test 3092 -ne `wc -c <'sockl.c'`; then
  793.     echo shar: \"'sockl.c'\" unpacked with wrong size!
  794. fi
  795. # end of 'sockl.c'
  796. fi
  797. if test -f 'sockl.h' -a "${1}" != "-c" ; then 
  798.   echo shar: Will not clobber existing file \"'sockl.h'\"
  799. else
  800. echo shar: Extracting \"'sockl.h'\" \(134 characters\)
  801. sed "s/^X//" >'sockl.h' <<'END_OF_FILE'
  802. X/* sockl.h */
  803. X
  804. X#ifndef SOCKL_H
  805. X#define SOCKL_H
  806. X
  807. X#define SOCKET_PATH_NAME "sweet_babboo"
  808. X#define SOCKET_QUEUE_LENGTH SOMAXCONN
  809. X
  810. X#endif
  811. END_OF_FILE
  812. if test 134 -ne `wc -c <'sockl.h'`; then
  813.     echo shar: \"'sockl.h'\" unpacked with wrong size!
  814. fi
  815. # end of 'sockl.h'
  816. fi
  817. if test -f 'sockl.nroff-man' -a "${1}" != "-c" ; then 
  818.   echo shar: Will not clobber existing file \"'sockl.nroff-man'\"
  819. else
  820. echo shar: Extracting \"'sockl.nroff-man'\" \(1531 characters\)
  821. sed "s/^X//" >'sockl.nroff-man' <<'END_OF_FILE'
  822. X.TH sockl 1
  823. X.SH Name
  824. sockl, sockt, isockl, isockt, disockl, disockt \- socket
  825. demonstration programs
  826. X.SH Syntax
  827. X.B "sockl
  828. X.PP
  829. X.B "sockt
  830. X.PP
  831. X.B "isockl
  832. X.PP
  833. X.B "isockt \fIremote_host\fP \fIport_number\fP
  834. X.PP
  835. X.B "disockl
  836. X.PP
  837. X.B "disockt \fIremote_host\fP \fIport_number\fP
  838. X.SH Description
  839. The
  840. X.B sockl,
  841. X.B isockl,
  842. and
  843. X.B disockl
  844. programs open sockets and listen for transmission requests.
  845. X.PP
  846. The
  847. X.B sockt,
  848. X.B isockt,
  849. and
  850. X.B disockt
  851. programs talk to the
  852. X.B sockl,
  853. X.B isockl,
  854. and
  855. X.B disockl
  856. processes, respectively.
  857. X.PP
  858. X.B sockl
  859. and
  860. X.B sockt 
  861. demonstrate AF_UNIX/SOCK_STREAM connections.
  862. X.B isockl
  863. and
  864. X.B isockt 
  865. demonstrate AF_INET/SOCK_STREAM connections.
  866. X.B disockl
  867. and
  868. X.B disockt 
  869. demonstrate AF_INET/SOCK_DGRAM unconnected communications.
  870. X.PP
  871. X.B sockl
  872. and
  873. X.B isockl
  874. accept only the first connection.
  875. X.B disockl
  876. never closes its socket, since datagrams
  877. do not contain reliable, intrinsic, end-of-transmission
  878. information.  The transmitted data is printed to stdout
  879. with a descriptive wrapper.
  880. X.PP
  881. Upon invocation,
  882. X.B isockl
  883. and
  884. X.B disockl
  885. print the port number of the socket they have opened;
  886. this is to be used as the
  887. X.I port_number
  888. argument to the corresponding talker.
  889. X.PP
  890. The talker may be on a machine separate from the
  891. listener, provided the
  892. X.I remote_host
  893. is listed in the talking machine's hosts database
  894. X(Yellow Pages or the
  895. X.I /etc/hosts
  896. file).
  897. X.SH Files
  898. X.B /etc/hosts
  899. X.SH See Also
  900. socket(2), gethostbyname(3n)
  901. X.SH Author
  902. Blair P. Houghton, Intel Corp., Arizona
  903. X.br
  904. X(bhoughto@pima.intel.com, uunet!intelhf!pima!bhoughto)
  905. END_OF_FILE
  906. if test 1531 -ne `wc -c <'sockl.nroff-man'`; then
  907.     echo shar: \"'sockl.nroff-man'\" unpacked with wrong size!
  908. fi
  909. # end of 'sockl.nroff-man'
  910. fi
  911. if test -f 'sockt.c' -a "${1}" != "-c" ; then 
  912.   echo shar: Will not clobber existing file \"'sockt.c'\"
  913. else
  914. echo shar: Extracting \"'sockt.c'\" \(1644 characters\)
  915. sed "s/^X//" >'sockt.c' <<'END_OF_FILE'
  916. X/* sockt.c -- open socket and talk into it */
  917. X/* (C) 1991 Blair P. Houghton, All Rights Reserved, copying and */
  918. X/* distribution permitted with copyright intact.        */
  919. X
  920. X#include <sys/types.h>
  921. X#include <sys/socket.h>
  922. X#include <sys/un.h>
  923. X#include "sockl.h"
  924. X
  925. X#ifdef __STDC__
  926. extern void    perror( char * );
  927. extern int    bind( int, struct sockaddr *, int );
  928. extern int    socket( int, int, int );
  929. extern int    write( int, char *, unsigned );
  930. extern char *    strcpy( char *, char *b );
  931. extern int    strlen( char * );
  932. extern void    exit( int );
  933. extern int    connect( int, struct sockaddr *, int );
  934. X#endif
  935. X
  936. char *line[] = {
  937. X    "Mary had a little lamb;\n",
  938. X    "Her fleece was white as snow;\n",
  939. X    "And everywhere that Mary went,\n",
  940. X    "She told everyone that Edison invented the telephone before Bell did.\n"
  941. X};
  942. int n_line = 4;
  943. X
  944. X#ifdef __STDC__
  945. void main( int argc, char *argv[] )
  946. X#else
  947. main(argc,argv)
  948. int argc; char *argv[];
  949. X#endif
  950. X{
  951. X
  952. X    int plug;                /* socket to "plug" into the socket */
  953. X    struct sockaddr_un socketname;    /* mode and path data for the socket */
  954. X    extern int n_line;
  955. X    extern char *line[];
  956. X    int i;
  957. X
  958. X    /* make a local-unix, stream-i/o, protocol-whatever plug */
  959. X    if ( (plug = socket( AF_UNIX, SOCK_STREAM, 0 )) < 0 )
  960. X    perror(argv[0]);
  961. X
  962. X    /* plug it into the listening socket */
  963. X    socketname.sun_family = AF_UNIX;
  964. X    strcpy( socketname.sun_path, SOCKET_PATH_NAME );
  965. X    if ( connect( plug, (struct sockaddr *) &socketname,
  966. X          sizeof socketname ) < 0 ) {
  967. X    perror(argv[0]);
  968. X    exit(__LINE__);
  969. X    }
  970. X
  971. X    /* say something into it; something historic */
  972. X    for ( i = 0; i < n_line; i++ )
  973. X    write( plug, line[i], strlen(line[i]) );
  974. X}
  975. END_OF_FILE
  976. if test 1644 -ne `wc -c <'sockt.c'`; then
  977.     echo shar: \"'sockt.c'\" unpacked with wrong size!
  978. fi
  979. # end of 'sockt.c'
  980. fi
  981. echo shar: End of archive 1 \(of 1\).
  982. cp /dev/null ark1isdone
  983. MISSING=""
  984. for I in 1 ; do
  985.     if test ! -f ark${I}isdone ; then
  986.     MISSING="${MISSING} ${I}"
  987.     fi
  988. done
  989. if test "${MISSING}" = "" ; then
  990.     echo You have the archive.
  991.     rm -f ark[1-9]isdone
  992. else
  993.     echo You still need to unpack the following archives:
  994.     echo "        " ${MISSING}
  995. fi
  996. ##  End of shell archive.
  997. exit 0
  998.